using System;
using UnityEngine;

namespace Com.LuisPedroFonseca.ProCamera2D
{
	public class ProCamera2DNumericBoundaries : BasePC2D, IPositionDeltaChanger, ISizeOverrider
	{
		public static string ExtensionName = "Numeric Boundaries";

		public Action OnBoundariesTransitionStarted;

		public Action OnBoundariesTransitionFinished;

		public bool UseNumericBoundaries = true;

		public bool UseTopBoundary;

		public float TopBoundary = 10f;

		public float TargetTopBoundary;

		public bool UseBottomBoundary = true;

		public float BottomBoundary = -10f;

		public float TargetBottomBoundary;

		public bool UseLeftBoundary;

		public float LeftBoundary = -10f;

		public float TargetLeftBoundary;

		public bool UseRightBoundary;

		public float RightBoundary = 10f;

		public float TargetRightBoundary;

		public bool IsCameraPositionHorizontallyBounded;

		public bool IsCameraPositionVerticallyBounded;

		public Coroutine BoundariesAnimRoutine;

		public Coroutine TopBoundaryAnimRoutine;

		public Coroutine BottomBoundaryAnimRoutine;

		public Coroutine LeftBoundaryAnimRoutine;

		public Coroutine RightBoundaryAnimRoutine;

		public int CurrentBoundariesTriggerID;

		public Coroutine MoveCameraToTargetRoutine;

		public bool UseElasticBoundaries;

		[Range(0f, 10f)]
		public float HorizontalElasticityDuration = 0.5f;

		public float HorizontalElasticitySize = 2f;

		[Range(0f, 10f)]
		public float VerticalElasticityDuration = 0.5f;

		public float VerticalElasticitySize = 2f;

		public EaseType ElasticityEaseType;

		private float _verticallyBoundedDuration;

		private float _horizontallyBoundedDuration;

		private int _pdcOrder = 4000;

		private int _soOrder = 2000;

		public int PDCOrder
		{
			get
			{
				return _pdcOrder;
			}
			set
			{
				_pdcOrder = value;
			}
		}

		public int SOOrder
		{
			get
			{
				return _soOrder;
			}
			set
			{
				_soOrder = value;
			}
		}

		protected override void Awake()
		{
			base.Awake();
			ProCamera2D.AddPositionDeltaChanger(this);
			ProCamera2D.AddSizeOverrider(this);
		}

		public Vector3 AdjustDelta(float deltaTime, Vector3 originalDelta)
		{
			if (!base.enabled || !UseNumericBoundaries)
			{
				return originalDelta;
			}
			IsCameraPositionHorizontallyBounded = false;
			ProCamera2D.IsCameraPositionLeftBounded = false;
			ProCamera2D.IsCameraPositionRightBounded = false;
			IsCameraPositionVerticallyBounded = false;
			ProCamera2D.IsCameraPositionTopBounded = false;
			ProCamera2D.IsCameraPositionBottomBounded = false;
			float num = Vector3H(ProCamera2D.LocalPosition) + Vector3H(originalDelta);
			if (UseLeftBoundary && num - ProCamera2D.ScreenSizeInWorldCoordinates.x / 2f < LeftBoundary)
			{
				num = LeftBoundary + ProCamera2D.ScreenSizeInWorldCoordinates.x / 2f;
				IsCameraPositionHorizontallyBounded = true;
				ProCamera2D.IsCameraPositionLeftBounded = true;
			}
			else if (UseRightBoundary && num + ProCamera2D.ScreenSizeInWorldCoordinates.x / 2f > RightBoundary)
			{
				num = RightBoundary - ProCamera2D.ScreenSizeInWorldCoordinates.x / 2f;
				IsCameraPositionHorizontallyBounded = true;
				ProCamera2D.IsCameraPositionRightBounded = true;
			}
			float num2 = Vector3V(ProCamera2D.LocalPosition) + Vector3V(originalDelta);
			if (UseBottomBoundary && num2 - ProCamera2D.ScreenSizeInWorldCoordinates.y / 2f < BottomBoundary)
			{
				num2 = BottomBoundary + ProCamera2D.ScreenSizeInWorldCoordinates.y / 2f;
				IsCameraPositionVerticallyBounded = true;
				ProCamera2D.IsCameraPositionBottomBounded = true;
			}
			else if (UseTopBoundary && num2 + ProCamera2D.ScreenSizeInWorldCoordinates.y / 2f > TopBoundary)
			{
				num2 = TopBoundary - ProCamera2D.ScreenSizeInWorldCoordinates.y / 2f;
				IsCameraPositionVerticallyBounded = true;
				ProCamera2D.IsCameraPositionTopBounded = true;
			}
			if (UseElasticBoundaries)
			{
				if (IsCameraPositionHorizontallyBounded)
				{
					_horizontallyBoundedDuration = Mathf.Min(HorizontalElasticityDuration, _horizontallyBoundedDuration + deltaTime);
					float value = 1f;
					if (HorizontalElasticityDuration > 0f)
					{
						value = _horizontallyBoundedDuration / HorizontalElasticityDuration;
					}
					num = ((!ProCamera2D.IsCameraPositionLeftBounded) ? Utils.EaseFromTo(Mathf.Min(RightBoundary - ProCamera2D.ScreenSizeInWorldCoordinates.x / 2f + HorizontalElasticitySize, Vector3H(_transform.localPosition)), RightBoundary - ProCamera2D.ScreenSizeInWorldCoordinates.x / 2f, value, ElasticityEaseType) : Utils.EaseFromTo(Mathf.Max(LeftBoundary + ProCamera2D.ScreenSizeInWorldCoordinates.x / 2f - HorizontalElasticitySize, Vector3H(_transform.localPosition)), LeftBoundary + ProCamera2D.ScreenSizeInWorldCoordinates.x / 2f, value, ElasticityEaseType));
				}
				else
				{
					_horizontallyBoundedDuration = Mathf.Max(0f, _horizontallyBoundedDuration - deltaTime);
				}
				if (IsCameraPositionVerticallyBounded)
				{
					_verticallyBoundedDuration = Mathf.Min(VerticalElasticityDuration, _verticallyBoundedDuration + deltaTime);
					float value2 = 1f;
					if (VerticalElasticityDuration > 0f)
					{
						value2 = _verticallyBoundedDuration / VerticalElasticityDuration;
					}
					num2 = ((!ProCamera2D.IsCameraPositionBottomBounded) ? Utils.EaseFromTo(Mathf.Min(TopBoundary - ProCamera2D.ScreenSizeInWorldCoordinates.y / 2f + VerticalElasticitySize, Vector3V(_transform.localPosition)), TopBoundary - ProCamera2D.ScreenSizeInWorldCoordinates.y / 2f, value2, ElasticityEaseType) : Utils.EaseFromTo(Mathf.Max(BottomBoundary + ProCamera2D.ScreenSizeInWorldCoordinates.y / 2f - VerticalElasticitySize, Vector3V(_transform.localPosition)), BottomBoundary + ProCamera2D.ScreenSizeInWorldCoordinates.y / 2f, value2, ElasticityEaseType));
				}
				else
				{
					_verticallyBoundedDuration = Mathf.Max(0f, _verticallyBoundedDuration - deltaTime);
				}
			}
			return VectorHV(num - Vector3H(ProCamera2D.LocalPosition), num2 - Vector3V(ProCamera2D.LocalPosition));
		}

		public float OverrideSize(float deltaTime, float originalSize)
		{
			if (!UseNumericBoundaries)
			{
				return originalSize;
			}
			Vector2 vector = new Vector2(RightBoundary - LeftBoundary, TopBoundary - BottomBoundary);
			if (UseRightBoundary && UseLeftBoundary && originalSize * ProCamera2D.GameCamera.aspect * 2f > vector.x)
			{
				return vector.x / ProCamera2D.GameCamera.aspect / 2f;
			}
			if (UseTopBoundary && UseBottomBoundary && originalSize * 2f > vector.y)
			{
				return vector.y / 2f;
			}
			return originalSize;
		}
	}
}
